package com.fofia.iotweb.web.dbdomain.services.admin;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.StaticLog;
import com.fofia.iotweb.common.CommonUtil;
import com.fofia.iotweb.common.IdHelper;
import com.fofia.iotweb.web.dbdomain.mappers.admin.SysMenuMapper;
import com.fofia.iotweb.web.dbdomain.mappers.admin.SysOperateMapper;
import com.fofia.iotweb.web.dbdomain.mappers.admin.SysRoleAuthorizeMapper;
import com.fofia.iotweb.web.dbdomain.models.admin.SysMenu;
import com.fofia.iotweb.web.dbdomain.models.admin.SysOperate;
import com.fofia.iotweb.web.dbdomain.models.admin.SysRoleAuthorize;
import com.fofia.iotweb.web.dbdomain.dto.SysFuncDto;
import com.fofia.iotweb.web.dto.KeyValueInt64Dto;
import com.mybatisflex.core.query.QueryWrapper;
import org.noear.snack.ONode;
import org.noear.solon.annotation.Component;
import com.fofia.iotweb.web.dbdomain.dto.MenuDto;
import org.noear.solon.annotation.Inject;

import java.util.*;
import java.util.stream.Collectors;


@Component
public class SysMenuService {

    @Inject("db")
    private SysMenuMapper menuMapper;
    @Inject("db")
    private SysOperateMapper operateMapper;
    @Inject("db")
    private SysRoleAuthorizeMapper roleAuthorizeMapper;
    /**
     *返回数据
     * @Author yushuo
     * @Description //TODO
     * @Date 14:04 2021/1/25
     * @Param []
     * @return java.util.List<com.easycms.domain.system.SysMenu>
     **/
    public List<SysMenu> getMenus(){

        QueryWrapper query= QueryWrapper.create()
                .orderBy(SysMenu::getMenuSort).asc();
        List<SysMenu> menus=menuMapper.selectListByQuery(query);

        return menus;

    }

    /**
     * 获取菜单信息
     * @param id
     * @return
     */
    public MenuDto getModel(long id){
        MenuDto model=new MenuDto();

        SysMenu menu=menuMapper.selectOneById(id);
        if(menu==null){
            return null;
        }

        //操作信息
        QueryWrapper fquery=QueryWrapper.create();
        fquery.eq(SysOperate::getMenuId,menu.getId());
        List<SysOperate> funcs=operateMapper.selectListByQuery(fquery);
        model.setMenu(menu);
        if(!funcs.isEmpty()){
            model.setFuncList(funcs);
        }

        return model;
    }

    /**
     * 获取菜单下拉 格式化一下
     * @return
     */
    public List<KeyValueInt64Dto> getMenuSelect(){

        List<SysMenu> menus=getMenus();

        List<KeyValueInt64Dto> menuSel=new ArrayList<>();
        menuSel.add(new KeyValueInt64Dto(0L,"请选择",""));
        if(menus.isEmpty()){
            return new ArrayList<>();
        }
        //一级菜单
        List<SysMenu> tops=menus.stream().filter(menu->menu.getParentId()==0L).toList();

        tops.forEach(menu->{
            KeyValueInt64Dto model=new KeyValueInt64Dto();
            model.setId(menu.getId());
            String name= StrUtil.format("¦--{}", menu.getMenuName());
            model.setName(name);
            menuSel.add(model);
            //二级菜单
            long pid=menu.getId();
            List<SysMenu> sons=menus.stream().filter(m->m.getParentId()==pid&&m.getMenuType()==0).toList();
            sons.forEach(son->{
                KeyValueInt64Dto model2=new KeyValueInt64Dto();
                model2.setId(son.getId());
                String name2=StrUtil.format("¦--¦--{}", son.getMenuName());
                model2.setName(name2);
                menuSel.add(model2);
                //三级菜单
                long sonPid=son.getId();
                List<SysMenu> sons2=menus.stream().filter(m->m.getParentId()==sonPid&&m.getMenuType()==0).toList();;
                sons2.forEach(m->{
                    KeyValueInt64Dto model3=new KeyValueInt64Dto();
                    model3.setId(m.getId());
                    String name3=StrUtil.format("¦┄┄¦┄┄¦--{}", m.getMenuName());
                    model3.setName(name3);
                    menuSel.add(model3);
                });
            });

        });


        return menuSel;
    }

    /**
     *
     * @author yushuo
     * @description 删除菜单和关联权限信息
     * @date 10:39 2021/1/29
     * @param
     * @return void
     **/
    //@Transactional(rollbackFor = EasyException.class )
    public void removeAll(String ids){

        List<Long> idArray = Arrays.asList(Convert.toLongArray(ids)) ;
         //删除menu表
        menuMapper.deleteBatchByIds(idArray);
         //删除按钮表
        QueryWrapper operateWrapper = QueryWrapper.create();
        operateWrapper.where(SysOperate::getMenuId).in(idArray);
        operateMapper.deleteByQuery(operateWrapper);
        //删除权限表
        QueryWrapper roleAuthorWrapper = QueryWrapper.create();
        roleAuthorWrapper.where(SysRoleAuthorize::getMenuPid).in(idArray)
                .or(SysRoleAuthorize::getMenuId).in(idArray);

        roleAuthorizeMapper.deleteByQuery(roleAuthorWrapper);

        //菜单有改动 删除全部权限缓存
        //PermissionCache.clearAll();
    }


    /**
     * 删除菜单下某个按钮
     * @param id
     */
    public void delfunc(long id){
        operateMapper.deleteById(id);
        //删除权限表
        QueryWrapper roleAuthorWrapper = QueryWrapper.create();
        roleAuthorWrapper.where(SysRoleAuthorize::getMenuId).eq(id);

        roleAuthorizeMapper.deleteByQuery(roleAuthorWrapper);
    }

    public List<SysMenu> getAllMenus(){

        List<SysMenu> menus=getMenus();

        if(!menus.isEmpty()){
            //一级菜单
            List<SysMenu> tops=menus.stream().filter(menu->menu.getParentId()==0L)
                    .collect(Collectors.toList());

            tops.forEach(menu->{
                menu.setTabId(CommonUtil.getMenuTabId(menu.getMenuUrl()));
                //二级菜单
                long pid=menu.getId();
                List<SysMenu> sons=menus.stream().filter(m->m.getParentId()==pid).collect(Collectors.toList());
                sons.forEach(son->{
                    son.setTabId(CommonUtil.getMenuTabId(son.getMenuUrl()));
                    //三级菜单
                    long sonPid=son.getId();
                    List<SysMenu> sons2=menus.stream().filter(m->m.getParentId()==sonPid).collect(Collectors.toList());
                    sons2.forEach(s->{
                        s.setTabId(CommonUtil.getMenuTabId(s.getMenuUrl()));
                    });
                    son.setChildren(sons2);
                });
                menu.setChildren(sons);
            });

            return tops;
        }
        return menus;
        // return menuMapper.selectList(query);

    }

    /**
     * @Author yushuo
     * @Description //保存菜单和按钮信息
     * @Date 11:17 2021/1/25
     * @Param SysMenu [menuDto]
     * @return void
     **/
    public void saveMenu(SysMenu menuDto,String funcs){
        if(menuDto.getParentId()==0){
            menuDto.setMenuUrl("");
            if(StrUtil.isEmpty(menuDto.getMenuIcon())){
                menuDto.setMenuIcon("fa fa-desktop");
            }

        }else
        {
            if(StrUtil.isEmpty(menuDto.getMenuIcon())){
                menuDto.setMenuIcon("fa fa-tag");
            }
        }
        if(StrUtil.isEmpty(menuDto.getRoleTag())){
            menuDto.setRoleTag("");
        }
        menuDto.setIframe(false);
        if(menuDto.getId()==0){
            addMenu(menuDto,funcs);
        }else{
            updateMenu(menuDto,funcs);
        }
    }


    /**
     *
     * @Author yushuo
     * @Description //TODO
     * @Date 11:36 2021/1/25
     * @Param SysMenu [dto]
     * @return void
     **/
    //@Transactional(rollbackFor =Exception.class )
    public void addMenu(SysMenu dto,String funcs){
        dto.setId(IdHelper.nextId());
        dto.setCreateTime(DateUtil.date());
        dto.setCreatePerson("admin");

        if(!StrUtil.isEmpty(dto.getMenuUrl())){
            dto.setMenuType(0);
        }
        if (dto.getParentId() == 0)
        {
            dto.setMenuLevel(1);
        }
        else
        {
            SysMenu menuLevel=menuMapper.selectOneById(dto.getParentId());

            dto.setMenuLevel(menuLevel.getMenuLevel()+1);
        }

        menuMapper.insert(dto);
        //操作

        if(!StrUtil.isEmpty(funcs)){
            List<SysOperate> operates=new ArrayList<>();
            //JSONUtil.toList(funcs,SysFuncDto.class);
            List<SysFuncDto> funcList= ONode.deserialize(funcs, (new ArrayList<SysFuncDto>(){}).getClass());

            for (SysFuncDto func: funcList){
                SysOperate operate=new SysOperate();
                operate.setId(IdHelper.nextId());
                operate.setMenuId(dto.getId());
                operate.setFuncTitle(func.getTitle());
                operate.setFuncSort(func.getFuncSort());
                operate.setRoleTag(func.getRoleTag());
                operates.add(operate);
            }

            if(!operates.isEmpty()){
                try{
                    operateMapper.insertBatch(operates);
                }catch (NullPointerException ex){
                   StaticLog.error(ex);
                }

            }
        }
    }


    /**
     *
     * @author yushuo
     * @description //TODO
     * @date 14:37 2021/1/25
     * @param dto, funcs
     * @return void
     **/
    //@Transactional(rollbackFor =Exception.class )
    public void updateMenu(SysMenu dto,String funcs){

        if(!StrUtil.isEmpty(dto.getMenuUrl())){
            dto.setMenuType(1);
        }
        if (dto.getParentId() == 0)
        {
            dto.setMenuLevel(1);
        }
        else
        {
            SysMenu menuLevel=menuMapper.selectOneById(dto.getParentId());
            dto.setMenuLevel(menuLevel.getMenuLevel()+1);
        }

        SysMenu menu=menuMapper.selectOneById(dto.getId());
        dto.setCreatePerson(menu.getCreatePerson());
        dto.setCreateTime(menu.getCreateTime());
        //更新操作
        menuMapper.update(dto);

        //操作
        Map<String, Object> delMap=new HashMap<>(1);
        delMap.put("menu_id",dto.getId());
        operateMapper.deleteByMap(delMap);

        if(!StrUtil.isEmpty(funcs)){
            List<SysOperate> operates=new ArrayList<>();
           List<SysFuncDto> funcList= ONode.deserialize(funcs, (new ArrayList<SysFuncDto>(){}).getClass());
            for (SysFuncDto func: funcList){
                SysOperate operate=new SysOperate();
                operate.setId(func.getId());
                operate.setMenuId(dto.getId());
                operate.setFuncTitle(func.getTitle());
                operate.setFuncSort(func.getFuncSort());
                operate.setRoleTag(func.getRoleTag());
                if(operate.getId()==0){
                    operate.setId(IdHelper.nextId());
                }
                operates.add(operate);
            }
            if(!operates.isEmpty()){
                operateMapper.insertBatch(operates);
            }
        }
    }
    private List<SysMenu> getFakeMenus(){
        List<SysMenu> menus=new ArrayList<>();
        SysMenu menu1=new SysMenu();
        menu1.setId(1L);
        menu1.setParentId(0L);
        menu1.setMenuName("系统管理");
        menu1.setMenuUrl("#");
        menu1.setRoleTag("#");
        menu1.setMenuSort(1);
        menu1.setMenuLevel(1);
        menu1.setMenuIcon("fa fa-bookmark");
        menus.add(menu1);

        SysMenu menu4=new SysMenu();
        menu4.setId(4L);
        menu4.setParentId(1L);
        menu4.setMenuName("用户信息");
        menu4.setMenuUrl("/admin/user/index");
        menu4.setRoleTag("admin-user-index");
        menu4.setMenuSort(4);
        menu4.setMenuLevel(2);
        menu4.setMenuIcon("fa fa-bookmark");
        menus.add(menu4);

        SysMenu menu5=new SysMenu();
        menu5.setId(5L);
        menu5.setParentId(1L);
        menu5.setMenuName("角色信息");
        menu5.setMenuUrl("/admin/role/index");
        menu5.setRoleTag("admin-role-index");
        menu5.setMenuSort(5);
        menu5.setMenuLevel(2);
        menu5.setMenuIcon("fa fa-bookmark");
        menus.add(menu5);
        return menus;
    }
}
